package client

import (
	"context"
	"fmt"
	"io/ioutil"
	v1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/json"
	"k8s.io/apimachinery/pkg/util/yaml"
	"k8s.io/client-go/util/retry"
	"k8s.io/klog/v2"
	"k8s.io/utils/pointer"
)

func GetDeployment(ns string) {
	clientSet, err := CreateClientSet()
	if err != nil {
		klog.Error(err)
	}
	opts := metav1.ListOptions{
		Watch: false,
	}
	dp, err := clientSet.AppsV1().Deployments(ns).List(context.TODO(), opts)
	for _, v := range dp.Items {
		klog.Info(v.Name, v.Status, v.APIVersion)
	}
}


func CreateDeployment(ns string, deploymentFile string) {
	clientSet, err := CreateClientSet()
	if err != nil {
		klog.Error(err)
	}
	deploymentsClient := clientSet.AppsV1().Deployments(ns)
	var (
		data       []byte
		deployment = &v1.Deployment{}
		replicas   int32
	)
	if data, err = ioutil.ReadFile(deploymentFile); err != nil {
		fmt.Print(err)
	}
	if data, err = yaml.ToJSON(data); err != nil {
		return
	}
	if err = json.Unmarshal(data, deployment); err != nil {
		return
	}
	deploymentName := deployment.ObjectMeta.Name
	replicas = 1
	deployment.Spec.Replicas = &replicas
	fmt.Println(deploymentName)
	if _, err = deploymentsClient.Get(context.TODO(), deploymentName, metav1.GetOptions{}); err != nil {
		if !errors.IsNotFound(err) {
			fmt.Println(err)
			return
		}
		if _, err = deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{}); err != nil {
			fmt.Println(err)
			return
		}
	} else {
		if _, err = deploymentsClient.Update(context.TODO(), deployment, metav1.UpdateOptions{}); err != nil {
			fmt.Println(err)
			return
		}
	}
	fmt.Println("deployment creat success!")
	return
}

func UpdateDeployment(ns string,deploymentName string,newRepsNum int)  {
	clientSet, err := CreateClientSet()
	if err != nil {
		klog.Error(err)
	}
	//RetryOnConflict 用于需要考虑更新冲突的情况下对资源进行更新
	//扩缩容
	retryErr:=retry.RetryOnConflict(retry.DefaultRetry, func() error {
		deploymentsClient := clientSet.AppsV1().Deployments(ns)
		opts:=metav1.GetOptions{}
		result,err :=deploymentsClient.Get(context.TODO(),deploymentName,opts)
		if err!=nil{
			panic(fmt.Errorf("Failed to get latest version of Deployment: %v",err))
		}
		//修改deployment的副本
		dp, err := clientSet.AppsV1().Deployments(ns).Get(context.TODO(), deploymentName,metav1.GetOptions{})
		if err!=nil{
			panic(err)
		}
		dprcNum:=dp.Spec.Replicas
		fmt.Printf("当前集群中要更新的deployment的副本数dprcNum为：%v\n",dprcNum)
		result.Spec.Replicas=pointer.Int32Ptr(int32(newRepsNum))
		fmt.Printf("当前集群中要更新的deployment的副本数newRepsNum为：%v\n",result.Spec.Replicas)
		_,updateErr:=deploymentsClient.Update(context.TODO(),result,metav1.UpdateOptions{})
		return updateErr
	})
	klog.Error(retryErr)
}